package com.youaishujuhui.devops.web.controller.host;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.socket.WebSocketSession;

import com.youaishujuhui.devops.web.cache.GlobalCache;
import com.youaishujuhui.devops.web.domain.game.Game;
import com.youaishujuhui.devops.web.domain.host.Host;
import com.youaishujuhui.devops.web.domain.manage.SysUser;
import com.youaishujuhui.devops.web.po.SSHExecResult;
import com.youaishujuhui.devops.web.service.PropertiesService;
import com.youaishujuhui.devops.web.service.SSHService;
import com.youaishujuhui.devops.web.service.game.GameService;
import com.youaishujuhui.devops.web.service.host.HostService;
import com.youaishujuhui.devops.web.util.Common;
import com.youaishujuhui.devops.web.util.WsUtil;
import com.youaishujuhui.devops.web.util.host.HostInstallTransferListener;
import com.youaishujuhui.devops.web.util.syslog.SystemLog;
import com.youaishujuhui.devops.web.vo.Result;

import cn.hutool.core.util.RuntimeUtil;

@Controller
@RequestMapping("/host/init")
public class HostInitController {
	
	@Autowired
	private SSHService sshService;
	
	@Autowired
	private PropertiesService propertiesService;
	
	@Autowired
	private GameService gameService;
	
	@Autowired
	private HostService hostService;
	
    @RequestMapping("/page")
    public ModelAndView page(Integer id, Integer gameId){
    	Host host = hostService.fetch(id);
    	
        return new ModelAndView("host/init")
        		.addObject("gameId", gameId)
        		.addObject("ip", host.getAvailablePublicIp())
        		.addObject("port", host.getSshPort())
        		.addObject("hostId", id);
    }
    
    @RequestMapping("/checkDuplicate")
    @ResponseBody
    public Result<String> checkDuplicate(String ip){
        Result<String> result = new Result<>();
        
        if (GlobalCache.hostInstallSet.contains(ip)) {
        	result.setCode(Result.FAIL);
        	result.setMsg("当前此主机已在初始化");
        	result.setData("1");
        	return result;
        }
        
        result.setData("0");
        
        result.setCode(Result.SUCCESS);
        result.setMsg("删除成功！");
        return result;
    }
    
    @RequestMapping("/init")
    @ResponseBody
    @SystemLog(module = "主机管理", oper = "初始化主机")
    public Result<String> init(Integer gameId, Integer hostId, String ip, Integer port, String user, String passwd){
        Result<String> result = new Result<>();
        
        if (GlobalCache.hostInstallSet.contains(ip)) {
        	result.setCode(Result.FAIL);
        	result.setMsg("当前此主机已在初始化");
        	return result;
        }
        
        GlobalCache.hostInstallSet.add(ip);
        
		// 获取登录用户账户
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		SysUser sysUser = (SysUser) request.getSession().getAttribute(Common.SESSION_LOGIN_USER_KEY);

		Game game = gameService.fetch(gameId);
		
		try {
			String shortName = "init_server_env_" + game.getNameEn();
			String fileName = shortName + ".tar.gz";
			String path = propertiesService.getHostInstallPath() + "/" + fileName;
			String installFilePath = "/root/" + fileName;
			
			WebSocketSession wsSession = GlobalCache.wsSessionCacheMap.get(sysUser.getUserName());

			if (!System.getProperty("os.name").toLowerCase().startsWith("win")){
				// 本机执行git pull保持更新脚本最新，只在linux上执行
				String cmd = "cd /data/" + shortName + "; git pull 2>&1";
				try {
					String output = RuntimeUtil.execForStr("sh", "-c", cmd);
					WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "执行git pull命令，输出为：" + output);
				} catch (IOException e) {
					e.printStackTrace();
					WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "执行git pull异常，请联系管理员");
					result.setCode(Result.FAIL);
					return result;
				}
				
				// 打包
				WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "正在打包，请等待");
				cmd = "cd /data; tar zcvf " + fileName + " ./" + shortName + " --exclude=./" + shortName + "/.git";
				try {
					String output = RuntimeUtil.execForStr("sh", "-c", cmd);
					WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "安装脚本和软件打包：输出为：" + output.replaceAll("\\n", "<br>"));
				} catch (IOException e) {
					e.printStackTrace();
					WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "执行安装脚本和软件打包异常，请联系管理员");
					result.setCode(Result.FAIL);
					return result;
				}
			}

			WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "开始传输安装包到目标主机，完成进度为：");

			// 文件拷过去
			try {
				sshService.SFTPPut(ip, port, user, passwd,
						path, installFilePath, new HostInstallTransferListener(ip, sysUser.getUserName()));
			} catch (IOException e) {
				e.printStackTrace();
				WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "传输安装包异常，请联系管理员");
				result.setCode(Result.FAIL);
				return result;
			}
			
			WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "安装包传输完成，开始解压，请等待");
			
			// 解压
			String cmd = "rm -rf /root/" + shortName + " ;tar zxvf " + installFilePath;
			try {
				SSHExecResult sshResult = sshService.exec(ip, port, user, passwd, cmd);
				WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, sshResult.getStdout().replaceAll("\\n", "<br>") + "安装包解压成功");
			} catch (IOException e) {
				e.printStackTrace();
				WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "安装包解压异常，请联系管理员");
				result.setCode(Result.FAIL);
				return result;
			}
			
			// 执行安装脚本
			cmd = "cd /root/" + shortName + "; sh ./install_rsa_1024_ro.sh 2>&1; sh ./init_server_env.sh 2>&1; cd ./zabbix_agent && sh ./install_zabbix_agent.sh " + ip;
			WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "执行命令：" + cmd);
			try {
				sshService.exec(ip, port, user, passwd, cmd, wsSession);
				WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "安装脚本执行完成");
			} catch (IOException e) {
				e.printStackTrace();
				WsUtil.send(wsSession, Common.HOST_INIT_DIV_ID_PREFIX + ip, "执行安装脚本异常，请联系管理员");
				result.setCode(Result.FAIL);
				return result;
			}
			
			// 修改主机状态为已初始化
			Host host = new Host();
			host.setHostId(hostId);
			host.setState(Common.HOST_STATE_INIT);
			hostService._update(host, "^state$");
			
			result.setCode(Result.SUCCESS);
		} catch (Exception e) {
			e.printStackTrace();
			result.setCode(Result.FAIL);
		} finally {
			GlobalCache.hostInstallSet.remove(ip);
		}

		return result;
    }

}
